<?php

namespace app\model\oa;

use app\model\BaseModel;
use think\model\concern\SoftDelete;

/**
 * 会议记录模型
 * 
 * @property int $id 主键ID
 * @property string $title 会议主题
 * @property int $meeting_room_id 会议室ID
 * @property string $start_time 开始时间
 * @property string $end_time 结束时间
 * @property int $organizer_id 组织者ID
 * @property string $participants 参会人员ID(JSON)
 * @property string $content 会议内容
 * @property string $decisions 会议决议
 * @property string $action_items 行动项目(JSON)
 * @property string $attachments 附件(JSON)
 * @property int $status 状态：1已预约 2进行中 3已完成 4已取消
 * @property string $remark 备注
 * @property int $create_time 创建时间
 * @property int $update_time 更新时间
 * @property int $delete_time 删除时间
 */
class MeetingRecords extends BaseModel
{
    use SoftDelete;

    protected $name = 'oa_meeting_records';
    protected $pk = 'id';

    // 会议状态常量
    const STATUS_BOOKED = 1;     // 已预约
    const STATUS_ONGOING = 2;    // 进行中
    const STATUS_COMPLETED = 3;  // 已完成
    const STATUS_CANCELLED = 4;  // 已取消

    // 字段类型转换
    protected $type = [
        'id' => 'integer',
        'meeting_room_id' => 'integer',
        'organizer_id' => 'integer',
        'status' => 'integer',
        'create_time' => 'timestamp',
        'update_time' => 'timestamp',
        'delete_time' => 'timestamp',
    ];

    /**
     * 关联会议室
     */
    public function meetingRoom()
    {
        return $this->belongsTo('app\model\oa\MeetingRoom', 'meeting_room_id', 'id');
    }

    /**
     * 关联组织者
     */
    public function organizer()
    {
        return $this->belongsTo('app\model\admin\User', 'organizer_id', 'id');
    }

    /**
     * 获取会议记录列表
     */
    public static function getList($params = [])
    {
        $query = self::with(['meetingRoom', 'organizer']);

        // 按会议室筛选
        if (!empty($params['meeting_room_id'])) {
            $query->where('meeting_room_id', $params['meeting_room_id']);
        }

        // 按组织者筛选
        if (!empty($params['organizer_id'])) {
            $query->where('organizer_id', $params['organizer_id']);
        }

        // 按状态筛选
        if (!empty($params['status'])) {
            $query->where('status', $params['status']);
        }

        // 按时间范围筛选
        if (!empty($params['start_date'])) {
            $query->where('start_time', '>=', $params['start_date'] . ' 00:00:00');
        }
        if (!empty($params['end_date'])) {
            $query->where('end_time', '<=', $params['end_date'] . ' 23:59:59');
        }

        // 按关键词搜索
        if (!empty($params['keyword'])) {
            $query->where(function($q) use ($params) {
                $q->where('title', 'like', '%' . $params['keyword'] . '%')
                  ->whereOr('content', 'like', '%' . $params['keyword'] . '%');
            });
        }

        return $query->order('start_time desc, id desc')->paginate($params['limit'] ?? 15);
    }

    /**
     * 获取今日会议
     */
    public static function getTodayMeetings($params = [])
    {
        $today = date('Y-m-d');
        $params['start_date'] = $today;
        $params['end_date'] = $today;
        return self::getList($params);
    }

    /**
     * 获取本周会议
     */
    public static function getThisWeekMeetings($params = [])
    {
        $week_start = date('Y-m-d', strtotime('this week'));
        $week_end = date('Y-m-d', strtotime('this week +6 days'));
        $params['start_date'] = $week_start;
        $params['end_date'] = $week_end;
        return self::getList($params);
    }

    /**
     * 检查会议室是否可用
     */
    public static function checkRoomAvailable($meeting_room_id, $start_time, $end_time, $exclude_id = 0)
    {
        $query = self::where('meeting_room_id', $meeting_room_id)
            ->where('status', 'in', [self::STATUS_BOOKED, self::STATUS_ONGOING])
            ->where(function($query) use ($start_time, $end_time) {
                $query->where(function($q) use ($start_time, $end_time) {
                    $q->where('start_time', '<=', $start_time)
                      ->where('end_time', '>', $start_time);
                })->whereOr(function($q) use ($start_time, $end_time) {
                    $q->where('start_time', '<', $end_time)
                      ->where('end_time', '>=', $end_time);
                })->whereOr(function($q) use ($start_time, $end_time) {
                    $q->where('start_time', '>=', $start_time)
                      ->where('end_time', '<=', $end_time);
                });
            });

        if ($exclude_id > 0) {
            $query->where('id', '<>', $exclude_id);
        }

        return $query->count() === 0;
    }

    /**
     * 创建会议记录
     */
    public static function createMeeting($data = [])
    {
        // 检查会议室是否可用
        if (!self::checkRoomAvailable($data['meeting_room_id'], $data['start_time'], $data['end_time'])) {
            throw new \Exception('该时间段会议室已被占用');
        }

        $meeting = new self();
        $meeting->title = $data['title'];
        $meeting->meeting_room_id = $data['meeting_room_id'];
        $meeting->start_time = $data['start_time'];
        $meeting->end_time = $data['end_time'];
        $meeting->organizer_id = $data['organizer_id'];
        $meeting->participants = !empty($data['participants']) ? json_encode($data['participants']) : '';
        $meeting->content = $data['content'] ?? '';
        $meeting->decisions = $data['decisions'] ?? '';
        $meeting->action_items = !empty($data['action_items']) ? json_encode($data['action_items']) : '';
        $meeting->attachments = !empty($data['attachments']) ? json_encode($data['attachments']) : '';
        $meeting->status = self::STATUS_BOOKED;
        $meeting->remark = $data['remark'] ?? '';

        return $meeting->save();
    }

    /**
     * 更新会议记录
     */
    public static function updateMeeting($id, $data = [])
    {
        $meeting = self::find($id);
        if (!$meeting) {
            return false;
        }

        // 如果修改了会议室或时间，需要检查冲突
        if (isset($data['meeting_room_id']) || isset($data['start_time']) || isset($data['end_time'])) {
            $room_id = $data['meeting_room_id'] ?? $meeting->meeting_room_id;
            $start_time = $data['start_time'] ?? $meeting->start_time;
            $end_time = $data['end_time'] ?? $meeting->end_time;

            if (!self::checkRoomAvailable($room_id, $start_time, $end_time, $id)) {
                throw new \Exception('该时间段会议室已被占用');
            }
        }

        if (isset($data['title'])) {
            $meeting->title = $data['title'];
        }
        if (isset($data['meeting_room_id'])) {
            $meeting->meeting_room_id = $data['meeting_room_id'];
        }
        if (isset($data['start_time'])) {
            $meeting->start_time = $data['start_time'];
        }
        if (isset($data['end_time'])) {
            $meeting->end_time = $data['end_time'];
        }
        if (isset($data['organizer_id'])) {
            $meeting->organizer_id = $data['organizer_id'];
        }
        if (isset($data['participants'])) {
            $meeting->participants = json_encode($data['participants']);
        }
        if (isset($data['content'])) {
            $meeting->content = $data['content'];
        }
        if (isset($data['decisions'])) {
            $meeting->decisions = $data['decisions'];
        }
        if (isset($data['action_items'])) {
            $meeting->action_items = json_encode($data['action_items']);
        }
        if (isset($data['attachments'])) {
            $meeting->attachments = json_encode($data['attachments']);
        }
        if (isset($data['status'])) {
            $meeting->status = $data['status'];
        }
        if (isset($data['remark'])) {
            $meeting->remark = $data['remark'];
        }

        return $meeting->save();
    }

    /**
     * 取消会议
     */
    public static function cancelMeeting($id, $organizer_id)
    {
        $meeting = self::where('id', $id)->where('organizer_id', $organizer_id)->find();
        if (!$meeting) {
            return false;
        }

        $meeting->status = self::STATUS_CANCELLED;
        return $meeting->save();
    }

    /**
     * 完成会议
     */
    public static function completeMeeting($id, $organizer_id)
    {
        $meeting = self::where('id', $id)->where('organizer_id', $organizer_id)->find();
        if (!$meeting) {
            return false;
        }

        $meeting->status = self::STATUS_COMPLETED;
        return $meeting->save();
    }

    /**
     * 获取参会人员
     */
    public function getParticipantsAttr($value)
    {
        return $value ? json_decode($value, true) : [];
    }

    /**
     * 获取行动项目
     */
    public function getActionItemsAttr($value)
    {
        return $value ? json_decode($value, true) : [];
    }

    /**
     * 获取附件
     */
    public function getAttachmentsAttr($value)
    {
        return $value ? json_decode($value, true) : [];
    }

    /**
     * 获取状态文本
     */
    public function getStatusTextAttr($value, $data)
    {
        $statusMap = [
            self::STATUS_BOOKED => '已预约',
            self::STATUS_ONGOING => '进行中',
            self::STATUS_COMPLETED => '已完成',
            self::STATUS_CANCELLED => '已取消',
        ];
        return $statusMap[$data['status']] ?? '未知';
    }

    /**
     * 搜索器：按会议室ID
     */
    public function searchMeetingRoomIdAttr($query, $value)
    {
        $query->where('meeting_room_id', $value);
    }

    /**
     * 搜索器：按组织者ID
     */
    public function searchOrganizerIdAttr($query, $value)
    {
        $query->where('organizer_id', $value);
    }

    /**
     * 搜索器：按状态
     */
    public function searchStatusAttr($query, $value)
    {
        $query->where('status', $value);
    }

    /**
     * 搜索器：按时间范围
     */
    public function searchTimeRangeAttr($query, $value)
    {
        if (is_array($value) && count($value) == 2) {
            $query->where('start_time', '>=', $value[0] . ' 00:00:00')
                  ->where('end_time', '<=', $value[1] . ' 23:59:59');
        }
    }

    /**
     * 搜索器：按关键词
     */
    public function searchKeywordAttr($query, $value)
    {
        $query->where(function($q) use ($value) {
            $q->where('title', 'like', '%' . $value . '%')
              ->whereOr('content', 'like', '%' . $value . '%');
        });
    }
}